// copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
// see COPYRIGHT for reuse legalities
//

#import "RIBGeneralPolygon.h"

@implementation RIBGeneralPolygon

+ initialize { return [RIBGeneralPolygon setVersion:1], self; }

- (BOOL)hasBoundingBox { return YES; }

- init
{
  [super init];

  nLoops = 0;
  nVertices = NULL;
  
  return self;
}

- setNLoops:(RtInt)newNLoops nVertices:(RtInt *)newNVertices 
     n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
     printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
{  
   nLoops = newNLoops;
   nVertices = newNVertices;
   [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];

   dirtyBoundingBox = TRUE;
   return self;
}

- free
{
  if (nVertices) { free(nVertices); }
  return [super free];
}

// this is used only internally, for setting a copy without freeing the original
- _setNVertices:(RtInt *)newNVertices
{
  int  i;


  if (newNVertices)
  {  nVertices = (long *)NXZoneMalloc([self zone], nLoops*sizeof(long));
     for (i = 0; i < nLoops; i++) 
     {  nVertices[i] = newNVertices[i];
     }
  }
  else
  {  nVertices = NULL;
  }
  return self;
}

- copyFromZone:(NXZone *)zone
{
   id   newCopy = [super copyFromZone:zone];

  [newCopy _setNVertices:nVertices];
  return newCopy;
}



- setNLoops:(RtInt)newNLoops { nLoops = newNLoops; dirtyBoundingBox = TRUE; return self; }
- setNVertices:(RtInt *)newNVertices { nVertices = newNVertices; dirtyBoundingBox = TRUE; return self; }

- (RtInt)nLoops { return nLoops; }
- (RtInt *)nVertices { return nVertices; }

- (BOOL)isMoot
{
  if (!nLoops) { return YES; }

  return NO;
}

- (BOOL)theSameAs:otherRIBCommand
{
  int    i;
  RtInt  *otherNVertices;


  if (nLoops != [otherRIBCommand nLoops])
  {  return NO;
  }
  otherNVertices = [otherRIBCommand nVertices];
  for (i = 0; i < nLoops; i++)
  {  if (nVertices[i] != otherNVertices[i])
     {  return NO;
     }
  }

  return [super theSameAs:otherRIBCommand];
}


- (BOOL)similarTo:otherRIBCommand 
{
  int    i;
  RtInt  *otherNVertices;


  if ([self class] != [otherRIBCommand class])
  {  return NO;
  }
  if (nLoops != [otherRIBCommand nLoops])
  {  return NO;
  }
  otherNVertices = [otherRIBCommand nVertices];
  for (i = 0; i < nLoops; i++)
  {  if (nVertices[i] != otherNVertices[i])
     {  return NO;
     }
  }

  return YES;
}


- renderSelf:(WW3DCamera *)camera  startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
{
  RiGeneralPolygonV(nLoops, nVertices, n, tokens, parms);
  return self;
}


- (BOOL)isMotionBlurrable { return YES; }


- (unsigned long int)maxSampleBandwidth {  return ([super maxSampleBandwidth] + (unsigned long int)((1 + nLoops) * sizeof(RtInt))); }


- writeEve:(NXStream *)stream atTabLevel:(int)tab
{
   int  i;


   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "GeneralPolygon {");
   for (i = 0; i < nLoops; i++)
   {  NXPrintf(stream, "%d ", nVertices[i]);
   }
   NXPrintf(stream, "} ");
   [super writeParameterList:stream];
   return self;
}

#define typeVector "i"
#define typeValues &nLoops

- read:(NXTypedStream*)stream 
{
    int version;

    [super read:stream];
    version = NXTypedStreamClassVersion(stream,"RIBGeneralPolygon");
    if (version == 0) NXReadTypes(stream,"i",&version), version=1;
    if (version == 1) {
	NXReadTypes(stream,typeVector,typeValues);
	nVertices = (long *)NXZoneMalloc([self zone], nLoops*sizeof(long));
	if (nVertices) {
	    NXReadArray(stream, "l", nLoops, nVertices);
	}
    } else {
    }
    return self;
}

- write:(NXTypedStream*)stream 
{
    [super write:stream];
    NXWriteTypes(stream,typeVector, typeValues);
    NXWriteArray(stream, "l", nLoops, nVertices);
    return self;
}

@end
